<script setup>
import 'animate.css'
import {reactive, ref} from "vue";
import {login, register} from "@/api/auth.js";
import { storeToRefs } from "pinia";
import { useUserStore } from "@/stores/userStore.js";
import {onMounted} from "vue";
import router from "@/router/index.js";
import 'animate.css'
import {showToast} from "@/components/toasts/LoginRegToast.js";
import {checkNameIfExist} from "@/api/auth.js";

const userAction = useUserStore()
const {userInfo} = storeToRefs(userAction)
const username = ref('')
const password = ref('')
const loginLoading = ref(false)
const reg_username = ref('')
const reg_password = ref('')
const reg_confirm_password = ref('')
const reg_nickname = ref('')
const pfpFile = ref()
const passwordStrength = ref('')
const regLoading = ref(false)

let isChoosePfp = false

onMounted(()=>{
  if (userInfo.value) {
    // 获取上次访问的路由（账号隔离）
    const userId = userInfo.value.id
    const lastRoute = userId ? localStorage.getItem('lastRoute_' + userId) : null
    const targetRoute = lastRoute || '/home/Welcome'
    router.replace(targetRoute)
  }
})

const isCheckUsername = ref(false)
const checkUsernameIcon = reactive({
  icon: ['far', 'circle-question'],
  style: {
    'text-danger': false,
    'text-success': false
  }
})
const isChecking = ref(false)
let checkUsername = {}
const checkingStatus = ref('正在检查可用性')
const isPass = ref(false)
const isValUsername = async () => {
  isPass.value = false
  const regex = /^[A-Za-z0-9]{3,16}$/;
  if (reg_username.value !== '') {
    if (!(regex.test(reg_username.value))) {
      checkUsernameIcon.icon = ['far', 'circle-xmark']
      checkUsernameIcon.style["text-danger"] = true
      isCheckUsername.value = false
      clearTimeout(checkUsername)
    } else {
      checkingStatus.value = '正在检查可用性'
      isChecking.value = true

      checkUsernameIcon.icon = ['far', 'circle-check']
      checkUsernameIcon.style["text-danger"] = false
      checkUsernameIcon.style["text-success"] = true

      isCheckUsername.value = true
      isChecking.value = true
      clearTimeout(checkUsername)

      checkUsername = setTimeout(async ()=>{
        try {
          const res = await checkNameIfExist(reg_username.value)
          if (res.data === 'taken') {
            checkingStatus.value = '用户名已被占用'
            isChecking.value = false
          } else if (res.data === 'pass') {
            checkingStatus.value = '可以使用此用户名'
            isPass.value = true
            isChecking.value = false
          } else {
            showToast('error', '服务器繁忙')
          }
        } catch (e) {
          showToast('error', '网络异常')
        }
      }, 1500)
    }
  } else {
    isCheckUsername.value = false
    checkUsernameIcon.icon = ['far', 'circle-question']
    checkUsernameIcon.style["text-danger"] = false
    checkUsernameIcon.style["text-success"] = false
  }
}

const validateEmail = (email) => {
  // 允许邮箱或用户名
  const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
  const userRegex = /^[A-Za-z0-9]{3,16}$/;
  return emailRegex.test(email) || userRegex.test(email);
}

const validatePassword = (pwd) => {
  return typeof pwd === 'string' && pwd.length >= 6 && pwd.length <= 32;
}

const getPasswordStrength = (pwd) => {
  if (!pwd) return '';
  if (pwd.length < 6) return '弱';
  if (/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/.test(pwd)) return '强';
  if (/^(?=.*[a-zA-Z])(?=.*\d).{6,}$/.test(pwd)) return '中';
  return '弱';
}

const onRegPasswordInput = () => {
  passwordStrength.value = getPasswordStrength(reg_password.value);
}

const clearLoginForm = () => {
  username.value = ''
  password.value = ''
}
const clearRegForm = () => {
  reg_username.value = ''
  reg_password.value = ''
  reg_confirm_password.value = ''
  reg_nickname.value = ''
  pfpFile.value = null
  passwordStrength.value = ''
  if (previewImage.value) {
    previewImage.value.style.display = 'none'
    previewImage.value.src = ''
  }
}

const handleToggleForm = () => {
  isToggleForm.value = !isToggleForm.value
  clearLoginForm()
  clearRegForm()
}

const loginHandle = async () => {
  if (!validateEmail(username.value)) {
    showToast('warning', '请输入有效的账号（用户名或邮箱）')
    return
  }
  if (!validatePassword(password.value)) {
    showToast('warning', '密码长度需为6-32位')
    return
  }
  loginLoading.value = true
  try {
    const res = await login(username.value, password.value)
    if (res.status === 200) {
      userAction.setUserInfo(res.data)
      clearLoginForm()
      return router.replace('/loading')
    }
  } catch (e) {
    // 错误提示由拦截器处理
  } finally {
    loginLoading.value = false
  }
}

const regHandle = async () => {
  if(reg_username.value === '' || reg_nickname.value === '' || reg_password.value === '' || reg_confirm_password.value === '') {
    showToast("warning", "请填写完整", "")
    return
  }
  if (!isPass.value) {
    showToast('warning', '请使用可用的账号名')
    return
  }
  if (reg_password.value !== reg_confirm_password.value) {
    showToast('warning', '两次密码不一致')
    return
  }
  if (!validatePassword(reg_password.value)) {
    showToast('warning', '密码长度需为6-32位')
    return
  }
  if (reg_nickname.value.length < 1 || reg_nickname.value.length > 12) {
    showToast('warning', '昵称需为1-12字符')
    return
  }
  if (pfpFile.value) {
    const allowTypes = ['image/jpeg', 'image/png', 'image/jpg']
    if (!allowTypes.includes(pfpFile.value.type)) {
      showToast('warning', '头像仅支持jpg/png格式')
      return
    }
    if (pfpFile.value.size > 2 * 1024 * 1024) {
      showToast('warning', '头像最大2MB')
      return
    }
  }
  regLoading.value = true
  try {
    const formData = new FormData()
    formData.append('username', reg_username.value)
    formData.append('name', reg_nickname.value)
    formData.append('password', reg_password.value)
    if (pfpFile.value) formData.append('avatar', pfpFile.value)
    const res = await register(formData)
    if (res.status === 200) {
      userAction.setUserInfo(res.data[0][0])
      clearRegForm()
      return router.replace('/loading')
    }
  } catch (e) {
    // 错误提示由拦截器处理
  } finally {
    regLoading.value = false
  }
}
const previewImage = ref()
const previewPfp = (e) => {
  const pfpText = document.querySelector('.pfp-text')
  if (e.target.files.length > 0) {
    isChoosePfp = true
    pfpText.innerText = '预览'
    pfpFile.value = e.target.files[0]
    previewImage.value.style.display = 'initial'
    previewImage.value.src = URL.createObjectURL(e.target.files[0])
  }
}

const isToggleForm = ref(true)
</script>

<template>
  <div class="vh-100 d-flex align-items-center justify-content-center">
    <div class="form-signin" v-if="isToggleForm">
      <form class="animate__animated animate__fadeIn animate__faster">
        <h1 class="h3 mb-3 fw-normal">你好，请登录</h1>
        <div class="form-floating mb-2">
          <input type="text" class="form-control" v-model="username" id="floatingInput" placeholder="Username">
          <label for="floatingInput"><font-awesome-icon :icon="['fas', 'user']" /> 账号</label>
          <span class="form-text"><small>* 不可使用昵称登录</small></span>
        </div>
        <div class="form-floating">
          <input type="password" class="text form-control" v-model="password" id="floatingPassword" placeholder="Password">
          <label for="floatingPassword"><font-awesome-icon :icon="['fas', 'lock']" /> 密码</label>
        </div>
        <div class="d-flex justify-content-between">
          <div class="my-3">还没有账号？<a class="text-primary" href="#" @click="handleToggleForm">注册</a></div>
        </div>
        <button class="btn btn-primary w-100 py-2" type="submit" :disabled="loginLoading" @click.prevent="loginHandle()">
          <span v-if="loginLoading" class="spinner-border spinner-border-sm me-2"></span>登录
        </button>
      </form>
    </div>
    <div v-else class="form-signin">
      <form class="animate__animated animate__fadeIn animate__faster">
        <h1 class="h3 mb-3 fw-normal">注册</h1>
        <div class="form-floating mb-2">
          <input type="text" class="form-control" @input="isValUsername" v-model="reg_username" id="floatingUsername" placeholder="Username">
          <label for="floatingUsername" ><font-awesome-icon :icon="['fas', 'user']" /> 账号</label>
          <div class="form-text d-flex align-items-center" v-if="isCheckUsername">
            <div>
              <div class="spinner-border text-primary" v-if="isChecking" style="width: 14px; height: 14px" role="status"></div>
              <font-awesome-icon class="text-success" v-if="isPass" :icon="['far', 'circle-check']"/>
              <font-awesome-icon class="text-danger" v-if="!isPass && !isChecking" :icon="['far', 'circle-xmark']"/>
            </div>
            &ensp;
            <small>{{ checkingStatus }}</small>
          </div>
          <div class="form-text d-flex align-items-center mb-3">
            <font-awesome-icon :icon="checkUsernameIcon.icon" :class="checkUsernameIcon.style"/>
            &ensp;
            <small>限英文字母或数字3-16字符</small>
          </div>
        </div>
        <div class="form-floating mb-2">
          <input type="text" class="form-control" v-model="reg_nickname" id="floatingNickname" placeholder="Username">
          <label for="floatingNickname"><font-awesome-icon :icon="['fas', 'address-book']" /> 昵称</label>
          <div class="form-text mb-3"><small>* 任意1-12字符</small></div>
        </div>
        <div class="form-floating mb-2">
          <input type="password" class="form-control" v-model="reg_password" id="floatingPassword" placeholder="Password" @input="onRegPasswordInput">
          <label for="floatingPassword"><font-awesome-icon :icon="['fas', 'lock']" /> 密码</label>
          <div class="form-text mb-1"><small>密码强度：{{ passwordStrength }}</small></div>
        </div>
        <div class="form-floating mb-2">
          <input type="password" class="form-control" v-model="reg_confirm_password" id="floatingConfirmPassword" placeholder="ConfirmPassword">
          <label for="floatingConfirmPassword"><font-awesome-icon :icon="['fas', 'lock']" /> 确认密码</label>
        </div>
        <div class="form-control py-3">
          <input id="pfp" type="file" accept=".jpg, .jpeg, .png" name="pfp" @change="previewPfp" class=" form-control mb-2">
          <label for="pfp" class="pfp-chooser"><font-awesome-icon :icon="['fas', 'file-image']" class="cursor-pointer" /> <span class="pfp-text">点此上传头像</span></label>
          <img src="" alt="Empty" ref='previewImage' id="previewImage" width="50" height="50">
        </div>
        <span class="form-text"><small>* 允许 jpg, jpeg, png格式, 最大2MB</small></span>
        <div class="my-3">已有账号？<a class="text-primary" href="#" @click="handleToggleForm">去登录</a></div>
        <button class="btn btn-primary w-100 py-2" :disabled="regLoading" @click.prevent="regHandle()" type="submit">
          <span v-if="regLoading" class="spinner-border spinner-border-sm me-2"></span>提交
        </button>
      </form>
    </div>
  </div>
</template>

<style>
.form-signin {
  margin: 35px auto;
  width: 320px;
}
#previewImage {
  margin-left: 10px;
  overflow: hidden;
  max-width: 40px;
  max-height: 40px;
  display: none;
  border-radius: 50%
}
.pfp-chooser {
  cursor: pointer;
}
</style>

